﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Web.Mvc;
using ControleRepresentante.Logic.Models;
using ControleRepresentante.Logic.Repositories;
using ControleRepresentante.Logic.Statistics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WebSite.Controllers;

namespace ControleRepresentante.UnitTests
{
    public static class TestScenarioClienteHelper
    {
        public static void DeleteCliente(this TestScenario testScenario, Guid clienteId)
        {
            IClienteRepository clienteRepository = testScenario.RepositoryProvider.GetRepository<IClienteRepository>();
            StatisticsBase statistics;
            int countBefore = clienteRepository.GetModels(out statistics).Count();
            using (ClienteController clienteController = new ClienteController(testScenario.RepositoryProvider, testScenario.SessionConfiguration, testScenario.ControllerExtensionProvider))
            {
                clienteController.Delete(clienteId);
                clienteController.Delete(clienteId, null);
                Assert.AreEqual(countBefore - 1, clienteRepository.GetModels(out statistics).Count());
            }
        }

        public static Guid CreateCliente(this TestScenario testScenario, Cliente cliente)
        {
            IClienteRepository clienteRepository = testScenario.RepositoryProvider.GetRepository<IClienteRepository>();
            StatisticsBase statistics;
            int countBefore = clienteRepository.GetModels(out statistics).Count();
            using (ClienteController clienteController = new ClienteController(testScenario.RepositoryProvider, testScenario.SessionConfiguration, testScenario.ControllerExtensionProvider))
            {
                clienteController.Create();
                foreach (Contato contato in cliente.Contatos)
                {
                    clienteController.ContatoInsert(contato.Tipo.ToString(), contato.Valor, contato.Observacao, contato.Principal);
                }
                foreach (Conta conta in cliente.Contas)
                {
                    clienteController.ContaInsert(conta.Banco, conta.Agencia, conta.Numero, conta.Observacao, conta.Principal);
                }
                foreach (Endereco endereco in cliente.Enderecos)
                {
                    clienteController.EnderecoInsert(endereco.Tipo.ToString(), endereco.Rua, endereco.Numero,
                                                      endereco.Complemento, endereco.Bairro, endereco.CEP,
                                                      endereco.Cidade, endereco.Estado, endereco.Observacao, endereco.Principal);
                }
                NameValueCollection collection = new NameValueCollection();
                foreach (AttributeValue attributeValue in cliente.AttributeValues)
                {
                    collection.Add("_" + attributeValue.Attribute.Name, attributeValue.Value);
                }
                if (cliente.ClienteJolitex != null)
                {
                    if (cliente.ClienteJolitex.Codigo.HasValue)
                    {
                        collection.Add("codigo", cliente.ClienteJolitex.Codigo.Value.ToString());
                    }
                    if (cliente.ClienteJolitex.Regiao.HasValue)
                    {
                        collection.Add("regiao", cliente.ClienteJolitex.Regiao.Value.ToString());
                    }
                }
                FormCollection formCollection = new FormCollection(collection);
                ActionResult actionResult = clienteController.Create(cliente.RazaoSocial, cliente.NomeFantasia, cliente.Vendedor.Id, cliente.CNPJ, cliente.InscricaoEstadual, cliente.ClienteDesde, formCollection);
                IEnumerable<Cliente> clientes = clienteRepository.GetModels(out statistics);
                Assert.AreEqual(countBefore + 1, clientes.Count());
                Cliente addedCliente = clientes.FirstOrDefault(x => x.RazaoSocial == cliente.RazaoSocial);
                Assert.AreEqual(cliente.RazaoSocial, addedCliente.RazaoSocial);
                Assert.AreEqual(cliente.NomeFantasia, addedCliente.NomeFantasia);
                Assert.AreEqual(cliente.CNPJ, addedCliente.CNPJ);
                Assert.AreEqual(cliente.InscricaoEstadual, addedCliente.InscricaoEstadual);
                Assert.AreEqual(cliente.ClienteDesde, addedCliente.ClienteDesde);
                Assert.AreEqual(cliente.Vendedor.Id, addedCliente.Vendedor.Id);
                Assert.AreEqual(cliente.Contatos.Count(), addedCliente.Contatos.Count());
                foreach (Contato contato in cliente.Contatos)
                {
                    Contato addedContato = addedCliente.Contatos.Single(x => x.Valor == contato.Valor);
                    Assert.AreEqual(contato.Tipo, addedContato.Tipo);
                    Assert.AreEqual(contato.Valor, addedContato.Valor);
                    Assert.AreEqual(contato.Observacao, addedContato.Observacao);
                    Assert.AreEqual(contato.Principal, addedContato.Principal);
                }
                Assert.AreEqual(cliente.Contas.Count(), addedCliente.Contas.Count());
                foreach (Conta conta in cliente.Contas)
                {
                    Conta addedConta = addedCliente.Contas.Single(x => x.Numero == conta.Numero);
                    Assert.AreEqual(conta.Agencia, addedConta.Agencia);
                    Assert.AreEqual(conta.Banco, addedConta.Banco);
                    Assert.AreEqual(conta.Numero, addedConta.Numero);
                    Assert.AreEqual(conta.Observacao, addedConta.Observacao);
                    Assert.AreEqual(conta.Principal, addedConta.Principal);
                }
                Assert.AreEqual(cliente.Enderecos.Count(), addedCliente.Enderecos.Count());
                foreach (Endereco endereco in cliente.Enderecos)
                {
                    Endereco addedEndereco = addedCliente.Enderecos.Single(x => x.Rua == endereco.Rua);
                    Assert.AreEqual(endereco.Tipo, addedEndereco.Tipo);
                    Assert.AreEqual(endereco.Rua, addedEndereco.Rua);
                    Assert.AreEqual(endereco.Numero, addedEndereco.Numero);
                    Assert.AreEqual(endereco.Complemento, addedEndereco.Complemento);
                    Assert.AreEqual(endereco.Bairro, addedEndereco.Bairro);
                    Assert.AreEqual(endereco.CEP, addedEndereco.CEP);
                    Assert.AreEqual(endereco.Cidade, addedEndereco.Cidade);
                    Assert.AreEqual(endereco.Estado, addedEndereco.Estado);
                    Assert.AreEqual(endereco.Observacao, addedEndereco.Observacao);
                    Assert.AreEqual(endereco.Principal, addedEndereco.Principal);
                }
                Assert.AreEqual(cliente.AttributeValues.Count(), addedCliente.AttributeValues.Count());
                foreach (AttributeValue attributeValue in cliente.AttributeValues)
                {
                    AttributeValue addedAttributeValue = addedCliente.AttributeValues.Single(x => x.Attribute.Name == attributeValue.Attribute.Name);
                    Assert.AreEqual(attributeValue.Value, addedAttributeValue.Value);
                }
                Assert.IsInstanceOfType(actionResult, typeof(RedirectToRouteResult));
                RedirectToRouteResult redirectToRouteResult = (RedirectToRouteResult)actionResult;
                Assert.AreEqual("Details", redirectToRouteResult.RouteValues["action"]);
                Assert.AreEqual(addedCliente.Id, redirectToRouteResult.RouteValues["id"]);
                return addedCliente.Id;
            }
        }

        internal static Guid CreateCliente(this TestScenario testscenario, string nome, Guid vendedorId)
        {
            Cliente cliente = new Cliente
            {
                NomeFantasia = nome,
                RazaoSocial = nome,
                Vendedor = new Vendedor {Id = vendedorId},
            };
            return testscenario.CreateCliente(cliente);
        }
    }
}
        